/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.buzzwords.resources;

import com.buzzwords.clientside.model.ClientBuzzword;
import com.buzzwords.clientside.model.ClientDefinition.DefinitionCategoryTypes;
import com.buzzwords.clientside.model.ClientDefinition.DefinitionSpeechTypes;
import com.buzzwords.clientside.model.ClientLocale;
import com.buzzwords.clientside.model.ClientObjectCounts;
import com.buzzwords.dataacess.Database;
import com.buzzwords.factories.BuzzwordDatabaseFactory;
import com.buzzwords.factories.DatabaseFactory;
import com.buzzwords.model.Buzzword;
import com.buzzwords.model.Definition;
import com.buzzwords.model.Locale;
import com.buzzwords.model.User;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import net.sf.json.JSONObject;

/**
 *
 * @author potlow
 */
@Path("/buzzword/")
public class BuzzwordResource {

    @Path("/get/")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public String getBuzzword(@QueryParam("word") @DefaultValue("") String word,
            @QueryParam("distance") Integer distance, @DefaultValue("") @QueryParam("area") String area) {

        if(word.isEmpty())
            return "No word submitted";
        if(area.isEmpty())
            return "No area aubmitted";

        // decode strings
        try {
            word = URLDecoder.decode(word, "UTF-8");
            area = URLDecoder.decode(area, "UTF-8");
        } catch (UnsupportedEncodingException uee) {
            return "";
        }

        DatabaseFactory databaseFactory = new BuzzwordDatabaseFactory();
        Database buzzwordDatabase = databaseFactory.getDatabase(BuzzwordDatabaseFactory.BUZZWORD_WORD);

        Map<String, String> cityStateCountry = Locale.extractCityStateCountryFromArea(area);
        List<Object> dbBuzzwords = buzzwordDatabase.performRead(word, Arrays.asList(Buzzword.BUZZWORD_LOCALES));

        // search for buzzwords by appropriate locale
        List<Object> objects = new ArrayList<Object>();
        for (Object object : dbBuzzwords) {
            Buzzword buzzword = (Buzzword) object;
            ClientBuzzword clientBuzzword = buzzword.getClientBuzzword();
            objects.add(clientBuzzword);
            for (Locale locale : buzzword.getLocales()) {
                if (distance == 0 && cityStateCountry.get("city").equalsIgnoreCase(locale.getCity())
                        && cityStateCountry.get("state").equalsIgnoreCase(locale.getState())
                        && cityStateCountry.get("country").equalsIgnoreCase(locale.getCountry())) {
                    ClientLocale clientLocale = locale.getClientLocale();
                    clientBuzzword.getLocales().add(clientLocale);
                    break;
                } else if (distance == 1 && cityStateCountry.get("state").equalsIgnoreCase(locale.getState())
                        && cityStateCountry.get("country").equalsIgnoreCase(locale.getCountry())) {
                    ClientLocale clientLocale = locale.getClientLocale();
                    clientBuzzword.getLocales().add(clientLocale);
                } else if (distance >= 2 && cityStateCountry.get("country").equalsIgnoreCase(locale.getCountry())) {
                    ClientLocale clientLocale = locale.getClientLocale();
                    clientBuzzword.getLocales().add(clientLocale);
                }
            }
        }

        ClientObjectCounts clientObjectCounts = new ClientObjectCounts(objects, objects.size());
        return JSONObject.fromObject(clientObjectCounts).toString();
    }

    @Path("/post/")
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public String postBuzzword(String json) {
        JSONObject JSONBuzzword = JSONObject.fromObject(json);

        DatabaseFactory databaseFactory = new BuzzwordDatabaseFactory();
        Database userDatabase = databaseFactory.getDatabase(BuzzwordDatabaseFactory.USER_UDID);
        Database buzzwordDatabase = databaseFactory.getDatabase(BuzzwordDatabaseFactory.BUZZWORD_WORD);

        // get or create user
        String udid = JSONBuzzword.getString("udid");
        User user = new User(udid);
        List<Object> dbUsers = userDatabase.performRead(user.getUDID(), new ArrayList<String>());
        if (!dbUsers.isEmpty() && dbUsers.size() == 1) {
            user = (User) dbUsers.get(0);
        } else {
            user.setUsername("Droid " + udid.substring(10, 16));
        }

        // get or create buzzword
        boolean createLocale = false;
        String word = JSONBuzzword.getString("word");
        Buzzword buzzword = new Buzzword(word);
        List<Object> dbBuzzwords = buzzwordDatabase.performRead(buzzword.getWord(), Arrays.asList(Buzzword.BUZZWORD_LOCALES));
        if(!dbBuzzwords.isEmpty() && dbBuzzwords.size() == 1) {
            buzzword = (Buzzword)dbBuzzwords.get(0);
        } else {
            createLocale = true;
        }

        // get or create locale
        String area = JSONBuzzword.getString("area");
        Locale locale = new Locale(area, buzzword);
        if(!createLocale) {
            for(Locale buzzwordLocale : buzzword.getLocales()) {
                if(locale.isRepresentedBy(area)) {
                    locale = buzzwordLocale;
                    break;
                }
            }
            createLocale = true;
        }
        if(createLocale)
            buzzword.getLocales().add(locale);

        // create and add definition
        Definition definition = new Definition(JSONBuzzword.getString("definition"),
                Enum.valueOf(DefinitionCategoryTypes.class, JSONBuzzword.getString("category")),
                Enum.valueOf(DefinitionSpeechTypes.class, JSONBuzzword.getString("partOfSpeech")),
                JSONBuzzword.getString("usage"), Float.valueOf(JSONBuzzword.getString("latitude")),
                Float.valueOf(JSONBuzzword.getString("longitude")), user);
        locale.getDefinitions().add(definition);

        // persist
        buzzwordDatabase.performCreate(buzzword);

        return "Buzzword stored";
    }
}
